package org.vacoor.xqq.ui.comp.tree;

import org.vacoor.nothing.ui.util.UIs;
import org.vacoor.xqq.core.bean.Buddy;
import org.vacoor.xqq.core.bean.Peer;

import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;

/**
 * QQ 风格节点渲染器
 * <p/>
 *
 * @author Vacoor
 */
public class CategoryTreeCellRenderer extends DefaultTreeCellRenderer {
    public static final Font BEST_FONT = UIs.getBestFont();
    /**
     * 树枝默认值
     */
    public static final Icon DEFAULT_BRANCH_EXPAND_ICON = new ImageIcon(CategoryTreeCellRenderer.class.getClassLoader().getResource("images/tree/expand.png"));
    public static final Icon DEFAULT_BRANCH_COLLAPSE_ICON = new ImageIcon(CategoryTreeCellRenderer.class.getClassLoader().getResource("images/tree/collapse.png"));

    public static final Color DEFAULT_BRANCH_BGC = new Color(255, 255, 255, 230);
    public static final Color DEFAULT_BRANCH_SELECTED_BGC = new Color(221, 221, 221, 230);
    public static final Color DEFAULT_BRANCH_NAME_FBC = Color.BLACK;
    public static final Color DEFAULT_BRANCH_COMMENT_FBC = Color.BLACK;

    /**
     * 树叶默认值
     */
    public static final Color DEFAULT_LEAF_BGC = new Color(255, 255, 255, 230);
    // public static final Color DEFAULT_LEAF_SELECTED_BGC = new Color(0xFFFFD7);
    public static final Color DEFAULT_LEAF_SELECTED_BGC = new Color(250, 230, 165, 230);
    // public static final Color DEFAULT_LEAF_SELECTED_BGC = new Color(205, 230, 250, 230);
    public static final Color DEFAULT_LEAF_NAME_FBC = Color.BLACK;
    public static final Color DEFAULT_LEAF_COMMENT_FBC = new Color(0x7F7F7F);

    // --------------------------------------------------------
    private JLabel category;

    private JPanel peer;
    private ShakeAvatar avatar;
    private JLabel nick;
    private JLabel mark;
    private JLabel summary;

    public CategoryTreeCellRenderer() {
        init();
    }

    private void init() {
        this.category = new JLabel();
        category.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));

        this.peer = new JPanel();
        this.avatar = new ShakeAvatar();
        this.nick = new JLabel();
        this.mark = new JLabel();
        this.summary = new JLabel();

        peer.setOpaque(false);
        peer.setLayout(new GridBagLayout());
        peer.setBorder(null);

        avatar.setOpaque(false);
        nick.setOpaque(false);
        mark.setOpaque(false);
        summary.setOpaque(false);
        summary.setForeground(DEFAULT_LEAF_COMMENT_FBC);

        //
        category.setFont(BEST_FONT);
        nick.setFont(BEST_FONT);
        mark.setFont(BEST_FONT);
        summary.setFont(BEST_FONT.deriveFont(BEST_FONT.getSize() - 1));
    }


    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        Component view;
        if (value instanceof CategoryNode) {
            view = rendererCategory(tree, (CategoryNode) value, selected, expanded, leaf, row, hasFocus);
        } else if (value instanceof PeerNode) {
            view = rendererPeer(tree, (PeerNode) value, selected, expanded, leaf, row, hasFocus);
        } else {
            view = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
        }

        Dimension size = calculatePreferredSize(tree, value, selected, expanded, leaf, row, hasFocus);
        view.setPreferredSize(size);

        return view;
    }

    protected Component rendererCategory(JTree tree, CategoryNode value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        // shaking 处理
        if (value.isShaking() && Shakeable.HIDDEN == value.nextShakeStatus()) {
            category.setText("");
            category.setIcon(null);
            return category;
        }
        if (selected || hasFocus) {
            category.setOpaque(true);
            category.setBackground(DEFAULT_BRANCH_SELECTED_BGC);
        } else {
            category.setOpaque(false);
        }
        category.setIcon(expanded ? DEFAULT_BRANCH_EXPAND_ICON : DEFAULT_BRANCH_COLLAPSE_ICON);
        category.setText(value.getName() + " [" + value.getOnlineCount() + "/" + value.getTotalCount() + "]");
        return category;
    }

    protected Component rendererPeer(JTree tree, PeerNode node, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        Peer value = node.getData();
        if (value.getAvatar() == null) {
            value.setAvatar(Buddy.DEFAULT_AVATAR);
        }
        avatar.setIcon(selected || hasFocus ? value.getBigAvatar() : value.getSmallAvatar());

        boolean shaking = node.isShaking();
        if (shaking) {
            avatar.setStatus(node.nextShakeStatus());
        } else if (!shaking && Shakeable.NORMAL != avatar.getStatus()) {
            avatar.resetStatus();
        }

        nick.setForeground(DEFAULT_LEAF_NAME_FBC);
        nick.setText(value.getName());
        mark.setText(value.getMark());
        summary.setText(value.getSummary());
        peer.setOpaque(true);
        peer.setBackground(selected ? DEFAULT_LEAF_SELECTED_BGC : DEFAULT_LEAF_BGC);

        boolean markIsEmpty = mark.getText() == null || mark.getText().length() < 1;

        peer.removeAll();

        nick.setForeground(DEFAULT_LEAF_NAME_FBC);
        if (selected) {
            peer.add(avatar, new GridBagConstraints(0, 0, 1, 2, 0, 0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(2, 10, 2, 5), 0, 0));
            if (!markIsEmpty) {
                peer.add(mark, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.CENTER, new Insets(3, 5, 2, -1), 0, 0));
                nick.setText("(" + nick.getText() + ")");
                nick.setForeground(DEFAULT_LEAF_COMMENT_FBC);
            }
            peer.add(nick, new GridBagConstraints(2, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.CENTER, new Insets(3, 5, 2, 2), 0, 0));
            peer.add(summary, new GridBagConstraints(1, 1, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.CENTER, new Insets(2, 5, 2, 2), 0, 0));
        } else {
            peer.add(avatar, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(2, 10, 2, 5), 0, 0));
            peer.add(markIsEmpty ? nick : mark, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.CENTER, new Insets(3, 5, 2, 2), 0, 0));
            peer.add(summary, new GridBagConstraints(2, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.CENTER, new Insets(3, 5, 1, 2), 0, 0));
        }
        return peer;
    }

    protected Dimension calculatePreferredSize(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        // 计算大小
        int width = 250;
//        int width = 200;
        if (tree.getWidth() > 0) {
            width = tree.getWidth();
        } else if (tree.getParent() != null && tree.getParent().getWidth() > 0) {
            width = tree.getParent().getWidth();
        }

        int height = 24;
        if (leaf) {
            height = 10 + (selected ? Buddy.BIG_AVATAR_SIZE.height : Buddy.SMALL_AVATAR_SIZE.height);
        }
        return new Dimension(width, height);
    }
}
